package services

import (
	"bbs-go/internal/models/constants"
	"strconv"
	"time"

	"github.com/mlogclub/simple/sqls"
	"github.com/mlogclub/simple/web/params"
	"gorm.io/gorm"

	"bbs-go/internal/models"
	"bbs-go/internal/repositories"
)

var ChatFriendsMessagesService = newChatFriendsMessagesService()

func newChatFriendsMessagesService() *chatFriendsMessagesService {
	return &chatFriendsMessagesService{}
}

type chatFriendsMessagesService struct {
}

func (s *chatFriendsMessagesService) Get(id int64) *models.ChatFriendsMessages {
	return repositories.ChatFriendsMessagesRepository.Get(sqls.DB(), id)
}

func (s *chatFriendsMessagesService) Take(where ...interface{}) *models.ChatFriendsMessages {
	return repositories.ChatFriendsMessagesRepository.Take(sqls.DB(), where...)
}

func (s *chatFriendsMessagesService) Find(cnd *sqls.Cnd) []models.ChatFriendsMessages {
	return repositories.ChatFriendsMessagesRepository.Find(sqls.DB(), cnd)
}

func (s *chatFriendsMessagesService) FindPageByParams(params *params.QueryParams) (list []models.ChatFriendsMessages, paging *sqls.Paging) {
	return repositories.ChatFriendsMessagesRepository.FindPageByParams(sqls.DB(), params)
}

func (s *chatFriendsMessagesService) FindPageByCnd(cnd *sqls.Cnd) (list []models.ChatFriendsMessages, paging *sqls.Paging) {
	return repositories.ChatFriendsMessagesRepository.FindPageByCnd(sqls.DB(), cnd)
}

func (s *chatFriendsMessagesService) Create(t *models.ChatFriendsMessages) error {
	return repositories.ChatFriendsMessagesRepository.Create(sqls.DB(), t)
}

func (s *chatFriendsMessagesService) Update(t *models.ChatFriendsMessages) error {
	return repositories.ChatFriendsMessagesRepository.Update(sqls.DB(), t)
}

func (s *chatFriendsMessagesService) Updates(id int64, columns map[string]interface{}) error {
	return repositories.ChatFriendsMessagesRepository.Updates(sqls.DB(), id, columns)
}

func (s *chatFriendsMessagesService) UpdateColumn(id int64, name string, value interface{}) error {
	return repositories.ChatFriendsMessagesRepository.UpdateColumn(sqls.DB(), id, name, value)
}

func (s *chatFriendsMessagesService) DeleteByArticleId(articleId int64) {
	sqls.DB().Model(models.ChatFriendsMessages{}).Where("article_id = ?", articleId).UpdateColumn("status", constants.StatusDeleted)
}

func (s *chatFriendsMessagesService) GetFriendsMessageList(page *sqls.Paging, userId int64, friendId int64) (models.FriendMessageListResponse, error) {
	limit := page.Limit
	offset := page.Limit * (page.Page - 1)
	if limit == 0 {
		limit = 10
	}
	db := sqls.DB()
	querySql := `select cfm.*,
	su.nickname as sender_user_nickname,su.avatar as sender_user_avatar,
	ru.nickname as receiver_user_nickname,ru.avatar as receiver_user_avatar
	from chat_friends_messages cfm  
	left join t_user su on cfm.sender_user_id = su.id 
	left join t_user ru on cfm.receiver_user_id = ru.id 
	where 1=1 and cfm.deleted_at is null `
	whereSql := ""
	whereVars := []interface{}{}

	whereSql += " and (cfm.sender_user_id = ? and receiver_user_id = ?) or (cfm.sender_user_id = ? and receiver_user_id = ?)"
	whereVars = append(whereVars, userId)
	whereVars = append(whereVars, friendId)
	whereVars = append(whereVars, friendId)
	whereVars = append(whereVars, userId)

	countSql := `select count(1)
	from chat_friends_messages cfm  
	where 1=1 `

	var total int64
	err := db.Raw(countSql+whereSql, whereVars...).Scan(&total).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return models.FriendMessageListResponse{}, err
	}

	list := []models.FriendMessageResponse{}
	orderBySql := " order by cfm.id desc LIMIT " + strconv.Itoa(limit) + " OFFSET " + strconv.Itoa(offset)
	err = db.Raw(querySql+whereSql+orderBySql, whereVars...).Find(&list).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return models.FriendMessageListResponse{}, err
	}

	return models.FriendMessageListResponse{
		List: list,
		Paging: &sqls.Paging{
			Page:  page.Page,
			Limit: page.Limit,
			Total: total,
		},
	}, nil
}

func (s *chatFriendsMessagesService) GetRecentFriendsMessageList(userId int64, friendId int64) (models.FriendMessageListResponse, error) {
	limit := 30
	offset := 0
	db := sqls.DB()
	querySql := `select cfm.*,
	su.nickname as sender_user_nickname,su.avatar as sender_user_avatar,
	ru.nickname as receiver_user_nickname,ru.avatar as receiver_user_avatar
	from chat_friends_messages cfm  
	left join t_user su on cfm.sender_user_id = su.id 
	left join t_user ru on cfm.receiver_user_id = ru.id 
	where 1=1 and cfm.deleted_at is null `
	whereSql := ""
	whereVars := []interface{}{}

	whereSql += " and cfm.created_at > ? "
	whereVars = append(whereVars, time.Now().AddDate(0, 0, -4).Format("2006-01-02 15:04:05"))

	whereSql += " and (cfm.sender_user_id = ? and cfm.receiver_user_id = ?) or (cfm.sender_user_id = ? and cfm.receiver_user_id = ?)"
	whereVars = append(whereVars, userId)
	whereVars = append(whereVars, friendId)
	whereVars = append(whereVars, friendId)
	whereVars = append(whereVars, userId)

	countSql := `select count(1)
	from chat_friends_messages cfm  
	where 1=1 `

	var total int64
	err := db.Raw(countSql+whereSql, whereVars...).Scan(&total).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return models.FriendMessageListResponse{}, err
	}

	list := []models.FriendMessageResponse{}
	orderBySql := " order by cfm.id desc LIMIT " + strconv.Itoa(limit) + " OFFSET " + strconv.Itoa(offset)
	err = db.Raw(querySql+whereSql+orderBySql, whereVars...).Find(&list).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return models.FriendMessageListResponse{}, err
	}

	return models.FriendMessageListResponse{
		List: list,
		Paging: &sqls.Paging{
			Page:  1,
			Limit: 50,
			Total: total,
		},
	}, nil
}

func (s *chatFriendsMessagesService) ChatFriendsMessageRead(userId int64, friendId int64) error {
	err := sqls.DB().Model(&models.ChatFriendsMessages{}).Where("is_read = ? and sender_user_id = ? and receiver_user_id = ?", false, friendId, userId).UpdateColumn("is_read", true).Error
	return err
}

func (s *chatFriendsMessagesService) GetFriendMessageUnReadCount(userId int64) ([]models.FriendMessageUnReadCountResponse, error) {
	db := sqls.DB()
	querySql := `select cfm.sender_user_id as friend_id,tu.nickname as friend_nickname,tu.avatar as friend_avatar,count(1) message_count 
	from chat_friends_messages cfm 
	left join t_user tu on cfm.sender_user_id =tu.id
	where cfm.deleted_at is null and cfm.is_read = 0 `
	groupSql := " group by cfm.sender_user_id"
	whereSql := ""
	whereVars := []interface{}{}

	whereSql += " and cfm.receiver_user_id = ? "
	whereVars = append(whereVars, userId)

	list := []models.FriendMessageUnReadCountResponse{}
	err := db.Raw(querySql+whereSql+groupSql, whereVars...).Find(&list).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, err
	}

	return list, nil
}
